home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’87 / Source ƒ.sit / Source ƒ / Pascal ƒ / TML Fkey.Pas ƒ / PROCPARM.TML < prev    next >
Encoding:
Text File  |  1992-06-28  |  6.1 KB  |  193 lines  |  [TEXT/EDIT]

  1. Mike Babulic (Compuserve ID 72307,314)
  2. 3827 Charleswood Dr. N.W., Calgary, Alberta
  3. CANADA, 
  4. T2L 2C7
  5. .
  6.     One of the weaknesses of TML Pascal is a lack of procedure parameters.
  7. My solution was write the UNIT "ProcParms". It exports two procedures:
  8. ProcParm and JumpTo(p:ProcPtr).
  9. .
  10. To use procedure parameters in your program you write a "dummy" procedure
  11. for each procedure you wish to pass as a parameter. The dummy procedure has 
  12. exactly the same parameters as the "passed procedure" except that it also has
  13. a pointer to the "procedure parameter" as its very last parameter (see the 
  14. example). It has no local declarations, and the only executable code is a 
  15. call to "ProcParm".
  16. .
  17.     ProcParm does 4 things:
  18.       1) it restores the stack to look exactly like it did on entry to the
  19.          dummy procedure.
  20.       2) it moves the last parameter (address of the "passed procedure") with
  21.          the dummy's return address from the stack to A0.
  22.       3) it moves the return address "down" the stack to where the last 
  23.          parameter used to be. THE STACK IS NOW EXACTLY AS IT WOULD HAVE BEEN IF
  24.          IF THE "PASSED PROCEDURE" HAD BEEN CALLED instead of the dummy!
  25.       4) it jumps to A0 (the start of the passed procedure)
  26. .
  27. JumpTo(p:ProcPtr) works in a simaler way to ProcParm, but its purpose is 
  28. quite different. It redirects a call to the dummy procedure to the 
  29. procedure pointed to by "p". The ProcPtr is supplied as an parameter of 
  30. JumpTo, rather than as the last parameter of the dummy procedure.
  31. .
  32. One word of warning:  ALL of the passed & dummy procedures _MUST_  be GLOBAL
  33. procedures.
  34. .
  35. ****************************** Example.pas *********************************
  36.  
  37. {              Shows how to use the ProcParms unit
  38.        
  39.  Author: Mike Babulic (Compuserve ID 72307,314)
  40.              3827 Charleswood Dr. N.W.,
  41.          Calgary, Alberta
  42.              CANADA, T2L 2C7
  43. }
  44.  
  45. PROGRAM Example(input,output);
  46.  
  47. USES MacIntf, ProcParms;
  48.  
  49. (*              {Lisa Pascal}
  50. {$U ProcParms}
  51.  
  52. USES MemTypes, ProcParms;
  53. *)   
  54.  
  55. {----------------- Procedures to be passed as parameters -----------------}
  56. {n.b.Procedures MUST be GLOBAL}
  57.  
  58.  PROCEDURE theFirst(a,b:integer);
  59.     begin
  60.       WriteLn(' FIRST ',a:3,b:3);
  61.     end;
  62.  
  63.   PROCEDURE theSecond(a,b:integer);
  64.     begin
  65.       WriteLn(a:3,' SECOND',b:3);
  66.     end;
  67.  
  68.   PROCEDURE theThird(a,b:integer);
  69.     begin
  70.       WriteLn(a:3,b:3,' THIRD');
  71.     end;  
  72.  
  73. {-------------- Shell to call procedures parameters with --------------}
  74.  
  75.   PROCEDURE dummy(a,b:integer;p:ProcPtr); {n.b.MUST be GLOBAL procedure}
  76.     begin
  77.       ProcParm;
  78.     end;  
  79.  
  80. {------------------ Routine with procedure parameter ------------------}
  81.     
  82.   PROCEDURE OneTwo(p:ProcPtr);
  83.     begin
  84.       dummy(9,10,p);
  85.     end;
  86. {------------- Using "JumpTo" to redirect a procedure call ------------} 
  87.   
  88.   PROCEDURE Three(a,b:integer);
  89.     begin
  90.       JumpTo(@theThird);
  91.     end;  
  92.  
  93. {----------------------------------------------------------------------}
  94.     
  95.   VAR ProcArray : ARRAY [1..3] OF ProcPtr;
  96.       i : integer;  
  97.       c:char;
  98.   BEGIN
  99.   
  100.     {Using Procedure Parameters}
  101.        OneTwo(@theFirst);    {will Execute theFirst}
  102.        OneTwo(@theSecond);   {will Execute theSecond}
  103.        
  104.     {Using JumpTo to redirect a procedure call}
  105.        Three(11,12);         {will Execute theThird}
  106.     WriteLn;
  107.  
  108.     {Another use of the ProcParm "dummy" routine}
  109.        ProcArray[1] := @theFirst;    
  110.        ProcArray[2] := @theSecond;
  111.        ProcArray[3] := @theThird;
  112.        for i := 3 downto 1 do
  113.          dummy(i,i+1,ProcArray[i]);
  114.       
  115.     WriteLn; WriteLn('Press RETURN to Quit');
  116.     Read(c);
  117.   END.
  118.  
  119. ***************************** ProcParms.pas ********************************
  120.  
  121. UNIT ProcParms;
  122. {
  123. ;Version 2.0                    ProcParms                  86/10/10
  124.  
  125. ;Author: Mike Babulic (Compuserve ID 72307,314)
  126. ;            3827 Charleswood Dr. N.W., Calgary, Alberta
  127. ;            CANADA, T2L 2C7
  128. ;  "Jump to ProcPtr" routine for Pascal
  129. ;     % allows procedures to be passed as parameters
  130. ;     % allows a procedure to be executed indirectly, given its address
  131. ;     % Example.pas shows how it is used
  132. ;
  133. ;  One of the weaknesses of TML (and other Mac Pascals) is that it doesn't
  134. ;  implement procedure and function parameters. This UNIT offers a method of 
  135. ;  overcoming that restriction.
  136. ;  
  137. ;  The ProcParm procedure allows you to write procedure/function parameters.
  138. ;
  139. ;  The JumpTo procedure redirects a procedure call.
  140. ;
  141. ;   ***** IMPORTANT *****  ALL of the passed & dummy procedures _MUST_  
  142. ;                          be GLOBAL procedures. 
  143. ;
  144.        ; see pp.C-4 thru C-6 of the TML manual to puzzle out
  145.        ; how this works (or should work anyway)
  146. ;
  147.  
  148. }
  149. { Refer to EXAMPLE.PAS to see how this unit is meant to be used}
  150.  
  151. INTERFACE
  152.  
  153. {$U ProcParm.REL}
  154.  
  155. USES MacIntf;
  156.  
  157.     PROCEDURE ProcParm;             EXTERNAL;
  158.     
  159.     PROCEDURE JumpTo(p:ProcPtr);    EXTERNAL;
  160.     
  161. IMPLEMENTATION
  162.     
  163. END.
  164.  
  165.  
  166. ****************************** ProcParm.asm ********************************
  167.  
  168. ;Version 2.0                    ProcParm                  86/10/07
  169. ;Author: Mike Babulic (Compuserve ID 72307,314)
  170. ;            3827 Charleswood Dr. N.W., Calgary, Alberta
  171. ;            CANADA, T2L 2C7
  172. ;  "Jump to ProcPtr" routine for Pascal
  173. ;     % allows procedures to be passed as parameters
  174. ;     % allows a procedure to be executed indirectly, given its address
  175. ;     % Example.pas shows how it is used 
  176. ;
  177.        ; see pp.C-4 thru C-6 of the TML manual to puzzle out
  178.        ; how this works (or should work anyway)
  179. ;
  180.         XDEF ProcParm
  181. ProcParm
  182.         UNLK    A6          ;restore frame pointer - A6 & stack - SP
  183.         MOVE.L  4(SP),A0    ;get procedure pointer
  184.         MOVE.L  (SP),4(SP)  ;write return address where the ProcPtr used to be
  185.         ADD.L   #4,SP       ;pop stack (postincrement cause illegal instruction)
  186.         JMP     (A0)        ;jump to procedure
  187. ;
  188.         XDEF JumpTo
  189. JumpTo
  190.         MOVE.L  4(SP),A0    ;get procedure pointer 
  191.         UNLK    A6          ;restore frame pointer - A6 & stack - SP
  192.         JMP     (A0)        ;jump to procedure
  193.